TCP重传分析 |
您所在的位置:网站首页 › fire dismiss sack区别 › TCP重传分析 |
1,重传基本原理 TCP协议是一种面向连接的可靠的传输层协议,它保证了数据的可靠传输。既然是可靠的传输,那对于丢包情况肯定有一套重传的机制。 TCP重传的基本原理:在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传。 上面的时序图,就是TCP重传的全部内容吗?好像很简单啊。 答案是:当然不是。 我们考虑一下下面这些问题: 1)RTO的时间是怎么来的? 2)每发一个包,都会启动一个定时器吗?那会不会导致定时器特别多,对系统性能有影响? 3)每个丢包都需要RTO超时之后,才能重传吗?对于偶尔丢了一个包,后面包都收到的场景,是否可以快速检测到该场景,并快速重传? 4)前面一个包丢了,后面所有的包都需要重传,即使已经发送成功;是否可以做到只重传已丢包的包,对于已收到的包不需要重传? 下面我们就来深入的讨论TCP重传机制的细节和原理,解决上面提到的问题。 2,RTO计算方法 RTO:英文全称是Retransmission TimeOut,即重传超时时间; RTO是一个动态值,会根据网络的改变而改变。RTO是根据给定连接的往返时间(RTT,全称:Round Trip Time)的测量值而计算出来的。 那么RTT又是如何测量得到的呢? 有有种测量方法: 1)重传队列中数据包的TCP控制块 TCP每发送一个数据包,就会把该数据包复制一份放到TCP重传队列中,数据包skb中的TCP控制块包含着一个变量tcp_skb_cb->when,记录了该数据包的第一次发送时间;收到该数据包的ACK时,再根据:当前时间 - when,得到RTT时间; 2)开启TCP Timestamp选项 需要开启tcp_timestamps选项,可以通过sysctl命令修改和查看; 当接收端和发送端同时支持TCP时戳选项时,发送端记录在TCP包头选项内的时戳可以被接收端随响应反射回来,发送端就可以利用响应报文的反射时戳计算出某个TCP包的即时往返传输时间。 RTT = 当前时间 - 数据包中Timestamp选项的回显时间 这个回显时间是该数据包发出去的时间,知道了数据包的接收时间(当前时间)和发送时间(回显时间),就可以轻松的得到RTT的一个测量值。 既然不用TCP Timestamp选项就能测量出RTT,为什么还要多此一举? 因为根据TCP Timestamp测出来的RTT更加准确;对于重传的数据包的响应,重传队列方法并不知道重传的开始时间,所以没办法采集起来作为一个样本;而TCP Timestamp方法则可以。 根据RTT计算RTO的方法: RTO = srtt >> 3 + rttvar RTO计算时,使用了一次指数平滑算法。 srtt为经过平滑后的RTT值,它代表着当前的RTT值,每收到一个ACK更新一次。 为了避免浮点运算,它是实际RTT值的8倍。 mdev为RTT的平均偏差,用来衡量RTT的抖动,每收到一个ACK更新一次。 mdev_max为上一个RTT内的最大mdev,代表上个RTT内时延的波动情况,有效期为一个RTT。 rttvar为mdev_max的平滑值,可升可降,代表着连接的抖动情况,在连接断开前都有效 3,超时定时器的实现 具体的TCP协议实现中,并不是每一个包都有一个定时器;如果每一个包都有一个定时器,那系统中定时器数据就太多了,会消耗很多资源,性能会比较差; 所以,TCP的实现中,都是一个连接对应一个超时定时器; 那一个连接对应一个定时器,那一个数据包的超时时间严格等于RTO时间吗?答应是:一个连接只有一个超时定时器,那么对于每个数据包,没办法做到超时时间严格等于RTO;但是可以保证超时时间不大于2*RTO。其实这就是性能和准确性的权衡考虑。 那TCP的超时定时器具体是怎实现的呢? 原则: 1.每一个报文在长期收不到确认都必须可以超时; 2.这个长期收不到中长期不能和测量的RTT相隔太远; 实现方法: a.发送TCP分段时,如果还没有重传定时器开启,那么开启它。 b.发送TCP分段时,如果已经有重传定时器开启,不再开启它。 c.收到一个非冗余ACK时,如果有数据在传输中,重新开启重传定时器。 d.收到一个非冗余ACK时,如果没有数据在传输中,则关闭重传定时器。 根据a和c(在c中,注意到ACK是非冗余的),任何TCP分段只要不被确认,超时定时器总会超时的。然而为何需要c呢?只有规则a存在的话,也可以做到原则1。实际上确实是这样的,但是为了不会出现过早重传,才添加了规则c,如果没有规则c,那么万一在重传定时器到期前,发送了一些数据,这样在定时器到期后,除了很早发送的数据能收到ACK外,其它稍晚些发送的数据的ACK都将不会到来,因此这些数据都将被重传。 4,快速重传 因为RTO超时重传的代价是比较大,会导致拥塞控制机制进行慢启动过程。对于因为网络毛刺或者随机因素导致的偶尔单个丢包,如果也进行RTO超时重传,会影响网络传输的性能。 对于这种场景,引入了快速重传机制。 发送方连续收到3次相同的ack,这个时候即使超时定时器还没有超时,也开始启动重传。 5,选择性重传 TCP通信时,如果发送序列中间某个数据包丢失,TCP会通过重传最后确认的包开始的后续包,这样原先已经正确传输的包也可能重复发送,急剧降低了TCP性能。为改善这种情况,发展出SACK(Selective Acknowledgment, 选择性确认)技术,使TCP只重新发送丢失的包,不用发送后续所有的包,而且提供相应机制使接收方能告诉发送方哪些数据丢失,哪些数据重发了,哪些数据已经提前收到等。 1)该功能可配置,通过系统参数:net.ipv4.tcp_sack配置;使用sysctl命令修改和查看。 2)CP头里加一个SACK选项,说明了接收到的数据的区间。 3)存在接收方Reneging情况,所谓Reneging的意思就是接收方有权把已经报给发送端SACK里的数据给丢了。这样干是不被鼓励的,因为这个事会把问题复杂化了,但是,接收方这么做可能会有些极端情况,比如要把内存给别的更重要的东西。所以,发送方也不能完全依赖SACK,还是要依赖ACK,并维护Time-Out,如果后续的ACK没有增长,那么还是要把SACK的东西重传,另外,接收端这边永远不能把SACK的包标记为Ack。 4)SACK会消费发送方的资源,试想,如果一个攻击者给数据发送方发一堆SACK的选项,这会导致发送方开始要重传甚至遍历已经发出的数据,这会消耗很多发送端的资源。 6,DSACK DSACK是在SACK的基础上做了一些扩展,主要用于对收到的重复报文进行了处理。 DSACK同样使用了与SACK一样的报文格式,唯一区别在于:第一个连续的block指定的是触发DSACK的重复报文的序号空间。 DSACK主要作用是:告诉发送方有哪些数据被重复接收了。 区分SACK和D-SACK的方法: D-SACK使用了SACK的第一个段来做标志, 1)如果SACK的第一个段的范围被ACK所覆盖,那么就是D-SACK 2)如果SACK的第一个段的范围被SACK的第二个段覆盖,那么就是D-SACK 引入了D-SACK,有这么几个好处: 1)可以让发送方知道,是发出去的包丢了,还是回来的ACK包丢了。 2)是不是自己的timeout太小了,导致重传。 3)网络上出现了先发的包后到的情况(又称reordering) 4)网络上是不是把我的数据包给复制了。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |